package com.javacoo.xservice.base.support.expression.internal;

import java.util.HashMap;
import java.util.Map;

import com.javacoo.xservice.base.support.expression.Expression;
import com.javacoo.xservice.base.support.expression.ExpressionParser;

/**
 * SpelExpressionParser
 * <p>说明:</p>
 * <li></li>
 * @author DuanYong
 * @since 2016年4月20日上午11:38:54
 */
public class SpelExpressionParser implements ExpressionParser {

	/**
	 * 使用SPEL的表达式解析器
	 */
	private org.springframework.expression.ExpressionParser realExpressionParser;

	/**
	 * 表达式实例缓存
	 */
	private static final Map<String, Expression> EXPRESSION_CACHE = new HashMap<String, Expression>();

	/**
	 * 表达式实施缓存开关
	 */
	private boolean allowCache = true;

	/**
	 * 
	 * 无参构造函数，new一个Spring EL的parser
	 * <p>
	 * 
	 */
	public SpelExpressionParser() {
		this.realExpressionParser = new org.springframework.expression.spel.standard.SpelExpressionParser();
	}

	/**
	 * 构造函数，根据Spring EL的parser构造相应的解析器对象---感觉没什么用途，应该删掉
	 * 
	 * @param parser
	 *            表达式解析器对象
	 */
	public SpelExpressionParser(
			org.springframework.expression.ExpressionParser parser) {
		this.realExpressionParser = parser;
	}

	/**
	 * 
	 * 根据指定的表达式从上下文中取值
	 * <p>
	 * 
	 * @param el
	 *            表达式
	 * @param root
	 *            存储表达式对应值的上下文
	 * @return 表达式对应的值
	 */
	@Override
	public Object getValue(String el, Object root) {
		Expression expression = this.parseExpression(el);
		return expression.getValue(root);
	}

	/**
	 * 
	 * 根据指定的表达式和目标数据类型从上下文中取值
	 * <p>
	 * 
	 * @param el
	 *            表达式
	 * @param root
	 *            存储表达式对应值的上下文
	 * @param clazz
	 *            目标数据类型对应的类
	 * @return 表达式对应的值
	 */
	@Override
	public <T> T getValue(String el, Object root, Class<T> clazz) {
		Expression expression = this.parseExpression(el);
		return expression.getValue(root, clazz);
	}

	/**
	 * 
	 * 根据指定的表达式将值设置到上下文中
	 * <p>
	 * 
	 * @param el
	 *            表达式
	 * @param value
	 *            表达式对应的值
	 * @param root 存储表达式对应值的上下文
	 */
	@Override
	public void setValue(String el, Object value, Object root) {
		Expression expression = this.parseExpression(el);
		expression.setValue(value, root);
	}

	/**
	 * 
	 * 解析表达式对象并缓存
	 * <p>
	 * 
	 * @param el
	 *            表达式
	 * @return Expression对象
	 */
	@Override
	public Expression parseExpression(String el) {
		Expression expression = null;

		/**
		 * 从缓存读取
		 */
		if (allowCache) {
			expression = EXPRESSION_CACHE.get(el);

			if (expression != null) {
				return expression;
			}
		}

		/**
		 * 如果无缓存，则编译新的表达式实施
		 */

		expression = new SpelExpression(this.realExpressionParser.parseExpression(el));

		/**
		 * 缓存该表达式实例
		 */
		if (allowCache) {
			EXPRESSION_CACHE.put(el, expression);
		}

		return expression;
	}

}
